<template>
  <div :id="self.name"
  style="position: relative;
          width: 100%;
          height: 90vh;
          margin: 0;
          padding: 0;"
  >
    
  </div>
</template>

<script>
import { ref, unref, watch } from 'vue'
import { init } from '/src/utils/base'
import { getSelection } from '/src/utils/index'
import { init as initBase } from './base'
import { exportWorkspace,saveAs } from '/src/utils'
import { init as sdp_workspace } from '../sdp_workspace/custom'
import { init as sdp_workspace_config } from '../sdp_workspace_config/custom'
import { init as sdp_project } from '../sdp_project/custom'
import { init as sdp_template } from '../sdp_template/custom'
import { init as sdp_sql } from '../sdp_sql/custom'

import { post } from "/src/api/index";

export default {
    emits: ['baseMounted'],
    
    setup() {
        let self = {}

        initBase(self)
        
        init(self)

        const baseMounted = (v) => {
          self.onMounted(v);
        }
        
        if (!self.sdp_workspace) {
          Array.from([
            {
              prop: 'sdp_workspace',
              method: sdp_workspace,
            },
            {
              prop: 'sdp_workspace_config',
              method: sdp_workspace_config,
            },
            {
              prop: 'sdp_project',
              method: sdp_project,
            },
            {
              prop: 'sdp_template',
              method: sdp_template,
            },
            {
              prop: 'sdp_sql',
              method: sdp_sql,
            },
          ]).forEach( ele => {
            self[ele.prop] = unref({module: ref(ele.prop)})
            ele.method(self[ele.prop])
          })
        }
        
        self.amis.editChangeScript = (a,b,c,d,e,f,name, more_data) => {
          if (!name) {
            name = a.props.name
          }

          let {
            formComponent
          } = self.amis.onAction(a,b,c,d,e,f)
          let formData ={...formComponent.getData(), ...c.data, ...more_data}
          
          if (!formData.db_classname) {
            return;
          }
          if (name == 'db_jdbcurl') {
            if (!formData.db_jdbcurl) {
              return
            }
          }
          
          let data
          if (formData.db_classname == 'com.mysql.jdbc.Driver'
            || formData.db_classname == 'com.mysql.cj.jdbc.Driver'
          ) {
            if (!formData.db_host || !formData.db_port || !formData.db_database) {
                return;
            }
            if (name == 'db_jdbcurl') {
              data = {
                db_host: formData.db_jdbcurl.split(':')[2].replace('//', ''),
                db_port: formData.db_jdbcurl.split(':')[3].split('/')[0],
                db_database: formData.db_jdbcurl.split('?')[0].split('/')[3],
              }
            } else {
              data = {
                db_jdbcurl: 'jdbc:mysql://' + formData.db_host + ':' + formData.db_port + '/' + formData.db_database + '?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai&tcpKeepAlive=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&tinyInt1isBit=false',
              }
            }
          } else if (formData.db_classname == 'org.h2.Driver') {
            if (!formData.db_database) {
              return;
            }
            if (name == 'db_jdbcurl') {
              data = {
                db_database: formData.db_jdbcurl.split(';')[0].split(':')[2],
              }
            } else {
              data = {
                jdbcurl: 'jdbc:h2:' + formData.db_database + ';AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1;MODE=MYSQL;DATABASE_TO_LOWER=TRUE'
              }
            }
          }
          if (data) {
            formComponent.setData(data)
            formComponent.emitChange()
          } else {
            self.amis.throw('无法分析')
          }
        }
        self.amis.onEditChange = {
          change: {
            actions: [
              {
                actionType: "custom",
                script: self.amis.editChangeScript,
              }
            ]
          }
        }

        self.amis.onEventEditSubmit = {
          click: {
            actions: [
              {
                actionType: "custom",
                script: (a,b,c,d,e,f) => {
                  self.amis.onAction(a,b,c,d,e,f, {
                    type:'edit',
                    module:unref(self.module),
                    prePost: (item) => {
                      if (item.db_port == '') {
                        if (!item.query_options) {
                          item.query_options = {}
                        }
                        if (!item.query_options.setnull) {
                          item.query_options.setnull = {}
                        }
                        item.query_options.setnull.db_port = ''
                      }
                      if (item.db_password == '******') {
                        delete item.db_password
                      }
                    }
                  })
                },
              },
            ],
          },
        }
        self.amis.onEventImportCancel = {
          click: {
            actions: [
              {
                actionType: "custom",
                script: (a,b,c,d,e,f) => {
                  let ret = self.amis.onAction(a,b,c,d,e,f)
                  let {
                    selectedItems
                  } = ret;
                  let dialogInfo = ret.formComponent.props.data.dialogInfo
                  dialogInfo.stop = 1
                  ret.formComponent.setData({dialogInfo})
                }
              }
            ]
          }
        }
        self.amis.onEventImportClose = {
          click: {
            actions: [
              {
                actionType: "custom",
                script: (a,b,c,d,e,f) => {
                  let ret = self.amis.onAction(a,b,c,d,e,f)
                  let {
                    selectedItems
                  } = ret;
                  if (ret.formComponent.props.data.button_import_warning_visible) {
                    self.amis.throw('请等待导入结束或停止导入')
                  }
                  b({actionType:'closeDialog'})
                }
              }
            ]
          }
        }
        self.amis.onEventImportSubmit = {
          click: {
            actions: [
              {
                actionType: "custom",
                script: (a,b,c,d,e,f) => {
                  let ret = self.amis.onAction(a,b,c,d,e,f)
                  let {
                    selectedItems
                  } = ret;
                  let dialogInfo = ret.formComponent.props.data.dialogInfo
                  delete dialogInfo.stop
                  let form = dialogInfo.form
                  let workspace_name = dialogInfo.form.workspace_name
                  if (!workspace_name) {
                    self.amis.throw('请输入工作区名称')
                  }
                  let file = ret.formComponent.props.data.file
                  if (!file) {
                    self.amis.throw('请选择导入文件')
                  }
                  ret.formComponent.setData({...ret.loading_true, button_import_warning_visible:true})
                  post('sdp_workspace', 'list', {name: form.workspace_name})
                  .then( data => {
                    if (data && data.length) {
                      ret.formComponent.setData({...ret.loading_false, button_import_warning_visible:false})
                      self.amis.throw(`工作区已经存在，请先删除后再重新导入：${form.workspace_name}`);
                    }

                    let workspaceName_dest = form.workspace_name
                    dialogInfo.getKey = (item, workspaceName, tableName, keys) => {
                      let key_ori = ''
                      for(let key in keys) {
                        key = keys[key]
                        if (!item[key]) {
                          if (tableName == 'sdp_workspace' && key == 'name') {
                            key_ori+=key+'='+workspaceName+';'
                            continue;
                          } else if (tableName != 'sdp_workspace' && key == 'workspace_name') {
                            key_ori+=key+'='+workspaceName+';'
                            continue;
                          } else if (tableName == 'sdp_sql' && key == 'name' && item.parameter_catalog == 'sql') {
                            key_ori+=key+'='+';'
                            continue;
                          } else if (tableName == 'sdp_template' && key == 'name' && item.name === '') {
                            key_ori+=key+'='+';'
                            continue;
                          } else {
                            console.error('miss key:'+key+','+tableName,item)
                            key_ori+=key+'='+';'
                            continue;
                          }
                        }
                        key_ori+=key+'='+item[key]+';'
                      }
                      return key_ori
                    }
                    dialogInfo.fire = () => {
                      if (dialogInfo.stop) {
                        if (dialogInfo.form.tip_last) {
                          dialogInfo.form.tip = dialogInfo.form.tip_last
                        }
                        dialogInfo.form.tip += '\n已经取消'
                        ret.formComponent.setData({...ret.loading_false, button_import_warning_visible:false,dialogInfo, tip:dialogInfo.form.tip})
                        ret.crudComponent.handleQuery();
                        return
                      }
                      if (dialogInfo.list_index == dialogInfo.list.length) {
                        if (dialogInfo.form.tip_last) {
                          dialogInfo.form.tip = dialogInfo.form.tip_last
                        }
                        dialogInfo.form.tip += '\n导入完成'
                        ret.formComponent.setData({...ret.loading_false, button_import_warning_visible:false,dialogInfo, tip:dialogInfo.form.tip})
                        ret.crudComponent.handleQuery();
                        return
                      }
                      let item = dialogInfo.list[dialogInfo.list_index]
                      let method = item['_method']
                      let tableName = item['_table_name']
                      let count = item['_count']
                      let msg = '正在导入' + tableName + ',共' + count + '条...'
                      if (dialogInfo.form.tip.indexOf(msg) < 0) {
                        if (dialogInfo.form.tip_last) {
                          dialogInfo.form.tip = dialogInfo.form.tip_last
                        }
                        dialogInfo.form.tip += '\n' + msg
                        dialogInfo.form.tip_last = dialogInfo.form.tip
                        dialogInfo.form.tip_index = 0
                      } else {
                        dialogInfo.form.tip_index++
                        dialogInfo.form.tip = dialogInfo.form.tip_last + '\n已导入'+dialogInfo.form.tip_index+'条'
                      }
                      ret.formComponent.setData({dialogInfo, tip:dialogInfo.form.tip})
                      delete item['_method']
                      delete item['_table_name']
                      delete item['_count']
                      post(method.split('/')[0], method.split('/')[1], item)
                        .then((data) => {
                          dialogInfo.list_index++
                          setTimeout(dialogInfo.fire, 10)
                        })
                        .catch((err) => {
                          dialogInfo.loading = false
                          dialogInfo.form.tip += '\n错误：' + JSON.stringify(err)
                          dialogInfo.form.tip += '\n方法：' + method
                          dialogInfo.form.tip += '\n数据：' + JSON.stringify(item)
                          ret.formComponent.setData({dialogInfo, tip:dialogInfo.form.tip})
                        })
                    },
                    exportWorkspace({...self, workspace_name: form.workspace_name, with_id:1})
                    .then((datas_ori) => {
                      {
                        let file = ret.formComponent.props.data.file
                        var reader = new FileReader()
                        reader.readAsText(file)
                        reader.onload = function () {
                          form.tip = '正在分析:' + file.name
                          ret.formComponent.setData({dialogInfo, tip:dialogInfo.form.tip})
                          dialogInfo.loading = true
                          dialogInfo.count = 0

                          dialogInfo.last_error_data = undefined

                          let datas = JSON.parse(this.result)
                          dialogInfo.list = []
                          for (let workspaceName in datas) {
                            let data = [
                              { 'sdp_workspace/add': { table: 'sdp_workspace', keys: 'name' }},
                              { 'sdp_workspace_config/add': { table: 'sdp_workspace_config', keys: 'workspace_name,name'}},
                              { 'sdp_project/add': { table: 'sdp_project', keys: 'workspace_name,name' }},
                              { 'sdp_template/add': { table: 'sdp_template', keys: 'workspace_name, project_name,name,file_type,project,package_name' }},
                              { 'sdp_sql/add': { table: 'sdp_sql', keys: 'workspace_name,table_name, parameter_catalog,parameter_catalog_type,name' }},
                            ]
                            for (let dataItem in data) {
                              dataItem = data[dataItem]
                              for (let method in dataItem) {
                                let tableName = dataItem[method].table
                                let keys = dataItem[method].keys.split(',').map( item => item.trim())
                                let dataList = datas[workspaceName][tableName]
                                let dataList_ori_map = {}
                                if (datas_ori && datas_ori[tableName]) {
                                  let dataList_ori = datas_ori[tableName]
                                  for (let item in dataList_ori) {
                                    item = {
                                      _method: method,
                                      _table_name: tableName,
                                      _count: dataList.length,
                                      ...dataList_ori[item],
                                    }
                                    let key_ori = dialogInfo.getKey(item, workspaceName_dest, tableName, keys)
                                    if (key_ori) {
                                      dataList_ori_map[key_ori] = item
                                    }
                                  }
                                }
                                for (let item in dataList) {
                                  item = {
                                    _method: method,
                                    _table_name: tableName,
                                    _count: dataList.length,
                                    ...dataList[item],
                                  }
                                  let key = dialogInfo.getKey(item, workspaceName_dest, tableName, keys)
                                  let item_ori = ''
                                  if (key) {
                                    item_ori = dataList_ori_map[key]
                                    item.sdp_key = key
                                  }
                                  delete item.id
                                  if (item_ori) {
                                    item.id = item_ori.id
                                    item._method = method.replace('/add', '/update')
                                    if (tableName == 'sdp_project' && item_ori.root_path && item_ori.root_path.indexOf('(root)') != 0) {
                                      delete item.root_path
                                    } else if (tableName == 'sdp_workspace') {
                                      delete item.db_password
                                    }
                                  }
                                  if ('sdp_sql/add' == method) {
                                    item = { ...item, disable_auto_param: 1 }
                                  }
                                  if ('sdp_workspace/add' == method) {
                                    item = { ...item, name: form.workspace_name }
                                  } else {
                                    item = {
                                      ...item,
                                      workspace_name: form.workspace_name,
                                    }
                                  }
                                  let itemNamesObject = {
                                    'sdp_template/add': ['file_template', 'remark'],
                                    'sdp_sql/add': ['parameter_sql', 'java_imports', 'remarks'],
                                  }
                                  if (method in itemNamesObject) {
                                    let itemNames = itemNamesObject[method]
                                    itemNames.forEach((itemName) => {
                                      try {
                                        let lines = item[itemName]
                                        if (lines) {
                                          let destLines = ''
                                          lines.forEach((line) => {
                                            destLines += line + '\n'
                                          })
                                          item[itemName] = destLines
                                        }
                                      } catch (ex) {}
                                    })
                                  }
                                  itemNamesObject = {
                                    'sdp_template/add': ['extra_info'],
                                    'sdp_sql/add': ['extra_info'],
                                  }
                                  if (method in itemNamesObject) {
                                    let itemNames = itemNamesObject[method]
                                    itemNames.forEach((itemName) => {
                                      try {
                                        if (item[itemName]) {
                                          item[itemName] = JSON.stringify(item[itemName], null, 2)
                                        }
                                      } catch (ex) {}
                                    })
                                  }
                                  dialogInfo.list.push(item)
                                }
                              }
                            }
                          }
                          dialogInfo.list_index = 0
                          dialogInfo.form.tip_last = ''
                          dialogInfo.form.tip = ''
                          ret.formComponent.setData({dialogInfo, tip:dialogInfo.form.tip})
                          dialogInfo.fire({...self})
                        }
                      }

                    })
                  })
                }
              }
            ]
          }
        }
        self.amis.onEventFileChange = {
          change: {
            actions: [
              {
                actionType: "custom",
                script: (a,b,c,d,e,f) => {
                  let ret = self.amis.onAction(a,b,c,d,e,f)
                  let workspace_name
                  if (c.data.file && c.data.file.name) {
                    workspace_name = c.data.file.name
                    if (workspace_name && workspace_name.indexOf('sdp_') == 0) {
                      workspace_name = workspace_name.substring(4)
                    }
                    workspace_name = workspace_name.split('.')[0]
                    let dialogInfo = {tip:'', form:{tip:'', workspace_name, tip_last:''}}
                    ret.formComponent.setData({dialogInfo})
                  }
                }
              }
            ]
          }
        }

        self.amis.onEventExportFile = {
          click: {
            actions: [
              {
                actionType: "custom",
                script: (a,b,c,d,e,f) => {
                  let ret = self.amis.onAction(a,b,c,d,e,f)
                  
                  let selectedItems = ret.crudComponent.props.store.selectedItemsAsArray
                  if (!selectedItems || !selectedItems.length) {
                    self.amis.throw('请先选择需要替换内容的条目')
                  }
                  if (selectedItems.length > 1) {
                    self.amis.throw('仅可选择一个条目进行导出')
                  }
                  ret.loadingComponent.setData(ret.loading_true)
                  let workspaceName = selectedItems[0].name
                  exportWorkspace({...self, workspace_name:workspaceName})
                  .then((datas) => {
                    ret.loadingComponent.setData(ret.loading_false)

                    let result = {}
                    result[workspaceName] = datas

                    result = JSON.stringify(result, null, 2)
                    var file = new File([result], 'sdp_' + workspaceName + '.txt', {
                      type: 'text/plain;charset=utf-8',
                    })
                    saveAs()(file)
                  })
                  .catch(ex => {
                    console.error('ex', ex)
                    ret.loadingComponent.setData(ret.loading_false)

                    self.amis.throw(`无法导出，错误：${ex}`);
                  })

                }
              },
            ],
          },
        }

        self.amis.onEventTestConnect = {
          click: {
            actions: [
              {
                actionType: "custom",
                script: (a,b,c,d,e,f) => {
                  self.amis.onAction(a,b,c,d,e,f, {
                    type:'custom',
                    module:unref(self.module),
                    method: 'test_connect',
                    config: { timeout: 5000 },
                    prePost: (item) => {
                      if (item.db_password == '******') {
                        delete item.db_password
                      }
                    }
                  })
                }
              },
            ],
          },
        }


        let columns = [
          {
            name: "db_classname",
            sortable: true,
            edit: {
              type: 'select',
              required: true,
              "options": [
                { label: 'Mysql', value: 'com.mysql.cj.jdbc.Driver' },
                { label: 'Mysql(旧版)', value: 'com.mysql.jdbc.Driver' },
                { label: 'H2', value: 'org.h2.Driver' },
              ].map(ele =>({label: ele.label + ' - ' + ele.value, value:ele.value})),
            },
          },
          {
            name: "db_host",
            edit: {
              name: '',
              type: 'group',
              body: [
                {
                  name: "db_host",
                  label: false,
                  type: "input-text",
                  clearable: true,
                  id: "u:3d25e8a95120",
                  onEvent: self.amis.onEditChange,
                },
                {
                  name:'',
                  label: '',
                  type: 'group',
                  body: [
                    {
                      name: 'anaJdbcurl',
                      type: 'button',
                      label: '分析jdbcurl',
                      onEvent: {
                        click: {
                          actions: [
                            {
                              actionType: "custom",
                              script: (a,b,c,d,e,f) => {
                                self.amis.editChangeScript(a,b,c,d,e,f,'db_jdbcurl', {
                                  db_host: 'mock',
                                  db_port: 'mock',
                                  db_database: 'mock',
                                })
                              }
                            }
                          ],
                        }
                      },
                    },
                    {
                      name: 'onlyJdbcurl',
                      type: 'button',
                      label: '仅使用jdbcurl',
                      onEvent: {
                        click: {
                          actions: [
                            {
                              actionType: "custom",
                              script: (a,b,c,d,e,f) => {
                                let {
                                  formComponent
                                } = self.amis.onAction(a,b,c,d,e,f)
                                
                                formComponent.setData({
                                  db_host: '',
                                  db_port: '',
                                  db_database: '',
                                })
                                formComponent.emitChange()
                              }
                            }
                          ],
                        }
                      },
                    }
                  ],
                },

              ],
            }
          },
          {
            name: "db_port",
            edit: {
              onEvent: self.amis.onEditChange,
            }
          },
          {
            name: "db_database",
            edit: {
              onEvent: self.amis.onEditChange,
            }
          },
          {
            name: "db_password",
            edit: {
              type: 'input-password',
              revealPassword: true,
            }
          },
          {
            name: 'db_jdbcurl',
            "type": "tpl",
            edit: {
              type: 'textarea',
              onEvent: self.amis.onEditChange,
            },
            copyable: true,
            "tpl": "${db_jdbcurl|truncate:16}",
            "popOverEnableOn": "${ db_jdbcurl && db_jdbcurl.length > 16 }",
            "popOver": {
              trigger: 'hover',
              "position": "left-top",
              "showIcon": true,
              "title": {
                type: "operation",
                buttons: [   
                  {
                    type: "button",
                    label: "复制",
                    "actionType": "copy",
                    "content": "${db_jdbcurl}",
                    id: "u:6e934ed74b84",
                  },
                ],
              },
              "body": {
                "type": "tpl",
                "tpl": "${db_jdbcurl}"
              }
            }
          },
        ]

        self.amis.init({columns,
          insert_edit_actions:[
            {
              type: 'button',
              label: '测试连接',
              level: 'primary',
              loadingOn: "${button_batch_test_connection_loading}",
              onEvent: self.amis.onEventTestConnect,
            },
          ],
          insert_edit_bulk_actions: [{
            type: 'button',
            label: '测试连接',
            level: 'primary',
            loadingOn: "${button_batch_test_connection_loading}",
            onEvent: self.amis.onEventTestConnect,
          },],
          append_header_actions: [
            {
              type: "button",
              align: "right",
              level: 'warning',
              label: "导入",
              //loadingOn: "${button_importr_loading}",
              //onEvent: self.amis.onEventImportFile,
              actionType: 'dialog',
              dialog: {
                title: "导入",
                size: "md",
                body: {
                  type: "form",
                  onInit:(a,b,c,d,e,f) => {
                    self.amis.enableDialogDrag();
                  },
                  affixFooter:true,
                  body: [
                    {
                      type: 'input-text',
                      name: 'dialogInfo.form.workspace_name',
                      label: '工作区',
                      required: true,
                    },
                    {
                      "type": "input-file",
                      "name": "file",
                      "label": "文件",
                      "accept": ".txt",
                      required: true,
                      asBlob: true,
                      // "receiver": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/upload/file",
                      "drag": true,
                      onEvent: self.amis.onEventFileChange,
                    },
                    {
                      type: 'textarea',
                      name: 'tip',
                      label: '提示信息',
                      minRows: 8,
                      maxRows: 8,
                    },
                  ],
                },
                "actions": [
                  {
                    "type": "button",
                    "label": "停止导入",
                    level: 'warning',
                    visibleOn: "${button_import_warning_visible}",
                    onEvent: self.amis.onEventImportCancel,
                  },
                  {
                    type: 'button',
                    label: '取消',
                    onEvent: self.amis.onEventImportClose,
                  },
                  {
                    "type": "button",
                    "label": "确认",
                    level: 'primary',
                    loadingOn: "${button_import_loading}",
                    onEvent: self.amis.onEventImportSubmit,
                  },
                ],
              },
            },
          ],
        })

        let schema = {
          ...self.amis.page_schema,
          body: [    
            {
              type: "crud",
              ...self.amis.commonSchema.crud,
              // multiple: false,
              bulkActions: [
                {...self.amis.commonSchema.bulkActions.delete},
                {...self.amis.commonSchema.bulkActions.edit},
                {...self.amis.commonSchema.bulkActions.batchUpdateValue},
                {
                  type: "button",
                  level: 'warning',
                  label: "导出",
                  loadingOn: "${button_export_loading}",
                  onEvent: self.amis.onEventExportFile,
                },
              ],
              filter: {
                title: '',
                persistData:unref(self.name)+'_filter',
                body: [
                  {...self.amis.commonSchema.filter.page_title},
                  {
                    type: "input-text",
                    name: "name_like",
                    label: false,
                    "clearable": true,
                    "placeholder": "请输入工作区名称",
                    static: false,
                    width: 200,
                    size:'sm',
                  },
                  {...self.amis.commonSchema.filter.search},
                ],
              },
            },
          ],
        }

        self.initAmis('#'+unref(self.name), schema)
        return {self:ref(self), baseMounted};
    },
};
</script>

